package com.yint.http.request;

import java.io.File;
import java.io.IOException;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.List;

import com.yint.http.bodys.HttpFormBody;
import com.yint.http.bodys.HttpMultiparBody;
import com.yint.http.bodys.HttpTextBody;
import com.yint.http.values.FileValue;
import com.yint.http.values.PartValue;

public class RequestWrapper
{
	private int connectTimeout = -1, readTimeout = -1;
	private String cookies = "";

	public void setConnectTimeout( int time )
	{
		this.connectTimeout = time;
	}

	public void setReadTimeout( int time )
	{
		this.readTimeout = time;
	}

	public void setCookies( String cookies )
	{
		this.cookies = cookies;
	}

	public String getCookies()
	{
		return cookies;
	}

	public void resetCookies( Request request )
	{
		request.addHeader( "Cookie", getCookies() );
	}

	/**
	 * 获取Get请求体
	 *
	 * @param url
	 * @return Response
	 */
	public Request get( String url )
	{
		return getBuilder().url( url ).build();
	}

	/**
	 * 获取Post请求体
	 *
	 * @param url
	 * @param params
	 *            post的参数
	 * @return
	 */
	public Request post( String url, List< PartValue > params )
	{
		return post( url, null, params );
	}

	/**
	 * 获取Post请求体
	 *
	 * @param url
	 * @param paramspost的参数
	 * @return
	 */
	public Request post( String url, String contextType, List< PartValue > params )
	{
		return buildPostRequest( url, contextType, params );
	}

	/**
	 * 获取Post请求体
	 * 
	 * @param url
	 * @param param
	 * @return
	 */
	public Request post( String url, String param )
	{
		return post( url, param, "" );
	}

	/**
	 * 获取Post请求体
	 * 
	 * @param url
	 * @param param
	 * @param contextType
	 * @param callback
	 * @throws IOException
	 */
	public Request post( String url, String param, String contextType )
	{
		Request.Builder builder = getBuilder();
		builder.url( url );
		if ( contextType != null && contextType.length() > 0 )
		{
			builder.addHeader( "Content-Type", contextType );
		}
		HttpTextBody body = new HttpTextBody();
		body.setParam( param );
		builder.post( body );
		return builder.build();
	}

	/**
	 * 获取单文件不带参数上传 Post请求体
	 *
	 * @param url
	 * @param callback
	 * @param file
	 * @param fileName
	 * @throws IOException
	 */
	public Request post( String url, File file, String fileName )
	{
		return post( url, null, file, fileName );
	}

	/**
	 * 获取单文件携带其他form参数上传 Post请求体
	 *
	 * @param url
	 * @param callback
	 * @param file
	 * @param fileName
	 * @param params
	 * @throws IOException
	 */
	public Request post( String url, List< PartValue > params, File file, String fileName )
	{
		return buildMultipartFormRequest( url, new File[] { file }, new String[] { fileName },
						params );
	}

	/**
	 * 组建post请求
	 *
	 * @param url
	 * @param params
	 * @return
	 */
	private Request buildPostRequest( String url, String contextType, List< PartValue > params )
	{
		Request.Builder builder = getBuilder();
		builder.url( url );
		if ( contextType == null )
		{
			contextType = "application/x-www-form-urlencoded";
		}
		builder.addHeader( "Content-Type", contextType );
		if ( params != null && params.size() > 0 )
		{
			HttpFormBody body = new HttpFormBody();
			for ( PartValue param : params )
			{
				body.addFormData( param );
			}
			builder.post( body );
		}

		return builder.build();
	}

	/**
	 * 组建 Multipart Form 请求
	 *
	 * @param url
	 * @param files
	 * @param fileKeys
	 * @param params
	 * @return
	 */
	private Request buildMultipartFormRequest( String url, File[] files, String[] fileKeys,
					List< PartValue > params )
	{
		Request.Builder builder = getBuilder();
		HttpMultiparBody body = new HttpMultiparBody();
		if ( params != null && params.size() > 0 )
		{
			for ( PartValue param : params )
			{
				body.addFormDataPart( param );
			}
			builder.addHeader( "Content-Type", "application/x-www-form-urlencoded" );
		}

		if ( files != null && files.length > 0 )
		{
			for ( int i = 0; i < files.length; i++ )
			{
				body.addFormDataPart( new FileValue( fileKeys[i], files[i] ) );
			}
			builder.addHeader( "Content-Type", "multipart/form-data" );
		}

		builder.url( url ).post( body );
		return builder.build();
	}

	private Request.Builder getBuilder()
	{
		Request.Builder builder = new Request.Builder();
		builder.setConnectTimeout( connectTimeout );
		builder.setReadTimeout( readTimeout );
		String cookies = getCookies();
		if ( cookies != null && cookies.length() > 0 )
		{
			builder.addHeader( "Cookie", cookies );
		}
		return builder;
	}

	/**
	 * 根据文件路径获取文件名
	 *
	 * @param path
	 * @return
	 */
	private String getFileName( String path )
	{
		int separatorIndex = path.lastIndexOf( "/" );
		return ( separatorIndex < 0 ) ? path : path.substring( separatorIndex + 1, path.length() );
	}

	/**
	 * 获取文件 mime类型
	 *
	 * @param path
	 * @return
	 */
	private String guessMimeType( String path )
	{
		FileNameMap fileNameMap = URLConnection.getFileNameMap();
		String contentTypeFor = fileNameMap.getContentTypeFor( path );
		if ( contentTypeFor == null )
		{
			contentTypeFor = "application/octet-stream";
		}
		return contentTypeFor;
	}

}
